import Taro from "@tarojs/taro"
import {http} from './http'
import {BAIDU_MAP_GEOCODING_API_URL, BAIDU_MAP_AK_KEY} from '../constants/baidu'
import {H5_GET_CITY, LIST_CITY} from '../constants/api'
import {CityLocation} from './server.interface'
import configStore from '../store'
import {autoLocation} from '../actions/location'
import {location as locationServer} from '../utils/location.service'
import {h5Wx} from "./h5.service";
import {newHttp} from "./request";
import {vcGetCache, vcSetCache} from "./tools";

const store = configStore()

interface GetCoordinateType {
  result: {
    comprehension: number
    confidence: number
    level: string
    location: { lng: number; lat: number }
    precise: number
  }
  status: number
}

class Location {
  ignore = false
  allCity: CityLocation[] = []

  async getLocationCity(longitude, latitude) {
    const baiduRet = await Taro.request<{ status: number; result: { addressComponent: { city: string } } }>({
      url: BAIDU_MAP_GEOCODING_API_URL,
      data: {
        ak: BAIDU_MAP_AK_KEY,
        location: latitude + ',' + longitude,
        coordtype: 'wgs84ll',
        output: 'json',
        pois: '0'
      }
    })
    if (baiduRet.statusCode != 200) {
      Taro.showToast({
        title: '通信失败',
        icon: 'none'
      })
    }
    const ret = baiduRet.data
    if (ret.status != 0) {
      Taro.showToast({
        title: '百度接口失败' + ret.status,
        icon: 'none'
      })
    }
    const allCity = await this.getAllcity()
    const cityName = ret.result.addressComponent.city
    if (JSON.stringify(allCity) === '{}') {
      return false
    }
    return allCity.find(item => item.area_name === cityName) || false
  }

  async getLocationNewH5City(longitude, latitude, coordtype) {
    const baiduRet = await newHttp.post(H5_GET_CITY, {location: latitude + ',' + longitude, coordtype})
    const ret = baiduRet.data
    if (ret.status) {
      Taro.showToast({
        title: '通信失败',
        icon: 'none'
      })
    }
    const allCity = await this.getAllcity()
    const cityName = ret.result.addressComponent.city
    if (JSON.stringify(allCity) === '{}') {
      return false
    }
    return allCity.find(item => item.area_name === cityName) || false
  }

  async getAllcity(): Promise<CityLocation[]> {
    let listCity = vcGetCache('listCity')
    if (!listCity) {
      listCity = await http.post<CityLocation[]>(LIST_CITY, {}) || []
    }
    vcSetCache('listCity', listCity, 1000)
    return listCity
  }

  async getCoordinate(address: string): Promise<{ lng: number; lat: number } | false> {
    try {
      if (process.env.TARO_ENV === 'weapp' || process.env.TARO_ENV === 'tt') {
        const ret = await Taro.request<GetCoordinateType>({
          url: BAIDU_MAP_GEOCODING_API_URL,
          data: {
            ak: BAIDU_MAP_AK_KEY,
            address: address,
            ret_coordtype: 'gcj02ll',
            output: 'json'
          }
        })
        if (ret.statusCode === 200 && ret.data) {
          if (ret.data.status === 0) {
            return ret.data.result.location
          } else {
            return false
          }
        } else {
          return false
        }
      } else {
        const ret = await newHttp.post(H5_GET_CITY, {address, ret_coordtype: 'gcj02ll'})
        if (ret.data) {
          if (ret.data.status === 0) {
            return ret.data.result.location
          } else {
            return false
          }
        } else {
          return false
        }
      }

    } catch (e) {
      return false
    }
  }

  // 添加一个location方法
  getLocation() {
    return new Promise(resolve => {
      if (process.env.TARO_ENV === 'weapp' || process.env.TARO_ENV === 'tt') {
        // 小程序
        Taro.getSetting({
          success: async (res) => {
            if (res.authSetting['scope.userLocation'] == false) {// 如果已拒绝授权，则打开设置页面
              resolve(null);
              Taro.showModal({
                title: '提示',
                content: '小程序需要定位权限, 请打开使用我的地理位置',
                success: (r) => {
                  if (r.confirm) {
                    Taro.openSetting()
                  }
                }
              })
            } else { // 第一次授权，或者已授权，直接调用相关api
              try {
                await Taro.getLocation({
                  type: 'wgs84',
                  success(r) {
                    resolve(r);
                  }
                })
              } catch (e) {
                if (e.errMsg === "getLocation:fail system permission denied") {
                  Taro.showModal({
                    title: '定位服务未开启',
                    content: '请在“设置->应用权限”中打开微信的位置权限',
                    complete: () => {
                      resolve(null);
                    }
                  })
                }
              }
            }
          }
        })
      } else if (process.env.TARO_ENV === 'h5') {
        if (process.env.P_ENV === 'lx') { // 灵锡
          h5Wx.getLocation(async (res) => {
            resolve(res)
          })
        } else {
          const ua: any = window.navigator.userAgent.toLowerCase();
          if (ua.match(/MicroMessenger/i) == 'micromessenger') {
            // 微信浏览器
            h5Wx.getLocation(async (res) => {
              resolve(res);
            }, 'wgs84')
          } else {
            // 不是微信浏览器
            resolve(null);
          }
        }
      }
    })
  }

  async autoLocation() {
    return new Promise<boolean>(async resolve => {
      if (this.ignore) {
        return resolve(false)
      }
      try {
        if (process.env.TARO_ENV === 'weapp' || process.env.TARO_ENV === 'tt') {
          Taro.getSetting({
            success(res) {
              if (res.authSetting['scope.userLocation'] == false) { // 如果已拒绝授权，则打开设置页面
                Taro.showModal({
                  title: '提示',
                  content: '小程序需要定位权限, 请打开使用我的地理位置',
                  success: (result) => {
                    if (result.confirm) {
                      Taro.openSetting()
                    }
                  }
                });
              } else {
                Taro.getLocation({
                  type: 'wgs84',
                  success: async (r) => {
                    const city = await locationServer.getLocationCity(r.longitude, r.latitude)
                    if (city) {
                      const {location} = store.getState()
                      if (location.region_id === 0) {
                        store.dispatch(autoLocation(city))
                      } else if (location.region_id !== city.region_id && !this.ignore) {
                        Taro.showModal({
                          content: '当前定位城市和您之前选择的城市不一致，是否切换到当前城市？',
                          success: (result) => {
                            if (result.confirm) {
                              store.dispatch(autoLocation(city))
                              Taro.navigateTo({
                                url: '/common/middle-page/list'
                              })
                            }
                            if (result.cancel) {
                              this.ignore = true
                            }
                          }
                        })
                      }
                      return resolve(true)
                    }
                  }
                })
              }
            }
          });
        } else {
          await h5Wx.getLocation(async (res) => {
            const city = await locationServer.getLocationNewH5City(res.longitude, res.latitude, 'gcj02')
            if (city) {
              const {location} = store.getState()
              if (location.region_id === 0) {
                store.dispatch(autoLocation(city))
              } else if (location.region_id !== city.region_id && !this.ignore) {
                await Taro.showModal({
                  content: '当前定位城市和您之前选择的城市不一致，是否切换到当前城市？',
                  success: (r) => {
                    if (r.confirm) {
                      store.dispatch(autoLocation(city))
                    }
                    if (r.cancel) {
                      this.ignore = true
                    }
                  }
                })
              }
              return resolve(true)
            }
          })
        }
      } catch (error) {
        return resolve(error)
      }
      return resolve(false)
    })
  }
}

export const location = new Location()
